<template>
  <a-config-provider :locale="locale">
    <div class="custom-view">
        <component
            v-if="currentView" v-bind:is="currentView"
            :ref="'component-view' + config.alias" :config="config"
            @jumpMenuByKey="jumpMenuByKey"
            :params="params"
            @customViewEvent="customViewEvent"
            :localParams="localParams"
            :customQueryData="customQueryData"/>
    </div>
  </a-config-provider>
</template>

<script>
/**
 * 自定义页面(自定义组件)
 */
import FormCustomPublic from "../FormCustomPublic.js";
import FormCustomQueryApi from "@/common/api/form/formCustomQuery.js";
import { Util } from '@lowcode/jpaas-base-lib'
import rxAjax from '@/assets/js/ajax.js';
import BusEvent from "../BusEvent";
import { markRaw } from 'vue'
import { PublicFunction } from "@lowcode/jpaas-share-component";
import shareFunction from "@/views/modules/form/FormCustomView/components/ColumnView/js/shareFunction.js"
import zhCN from 'ant-design-vue/es/locale/zh_CN';

import {ShareFormBoListPreview} from '@lowcode/jpaas-share-component';
import createRoutes from "@/views/layout/js/create-routes";
import useMain from "@/stores/useMain";
import { mapState } from 'pinia'
export default {
    name: "customView",
    mixins: [FormCustomPublic, BusEvent,createRoutes],
    data() {
        return {
            locale:zhCN,
            currentView: "",
            customQueryData: [],
            defScript: "export default {\n" +
                "    props: {\n" +
                "        customQueryData: {type: Array,default:[]},\n" +
                "        config: {type: Object,default:{}},\n" +
                "        params: {type: Object,default:{}},\n" +
                "    },\n" +
                "    data(){\n" +
                "        return {\n" +
                "        }\n" +
                "    },\n" +
                "    created(){},\n" +
                "    methods:{\n" +
                "        customViewEvent(data){\n" +
                "            this.$emit('customViewEvent',{component:this.config.alias,params:data});\n" +
                "        }\n" +
                "    },\n" +
                "    watch:{}\n" +
                "}",
            params: {},
            refAlias: ""
        }
    },
    computed:{
        ...mapState(useMain,['curApp'])
    },
    created() {
        this.init();
    },
    methods: {
        getCurMenu(key,menus){
            for (let item of menus){
                if(item.menuKey === key){
                    return item
                }
                if(item.children && item.children.length > 0){
                    let o = this.getCurMenu(key,item.children)
                    if(o){
                        return o
                    }
                }
            }
        },
        async jumpMenuByKey({menuKey,appId,params}){
            let id = appId || this.curApp.appId || '';
            if(!id){ return }
            let menu = this.cacheLeftMenus[id];
            if(!menu){
                menu = await this.actionMenus(appId)
            }
            let curMenu = this.getCurMenu(menuKey,menu);
            if(!curMenu){
                this.$message.warning('没有找到当前菜单~')
                return;
            }
            curMenu.params = { ...(curMenu.params || {}),...params}
            /*
            * 在ac-main中的src/views/layout/LayoutMethods.js
            * 中接收发出的事件
            * */
            this.$bus.emit('jumpOpenMenu',curMenu)
        },
        refreshChange() {
            this.init();
        },
        handleCustomFun(btn) {
            let refStr = 'component-view' + this.config.alias;
            this.$refs[refStr][btn.btnClick](btn);
        },
        init() {
            let self = this;
            let refStr = 'component-view' + this.config.alias;
            this.refAlias = refStr;
            if (!this.config) {
                return;
            }

            //调用自定义查询.
            this.initQuery();
            //vue文件
            if (self.config.mode === "file") {
                if (self.config.path) {
                    self.currentView = self.loadView(self.config.path);
                }
            } else {
                //调用JS
                this.initJs()
            }

        },
        //初始化配置的JS
        initJs(){
            //加载js
            let jsScript = "";
            let script_ = "";
            if (this.config.jsScript) {
                jsScript = this.config.jsScript;
            } else {
                //设置默认js
                jsScript = this.defScript;
            }
            let vueJs = Util.replaceDefault(jsScript);
            vueJs = `let sc=${vueJs};return sc;`;
            script_ = new Function(vueJs)();
            if (this.config.template) {
                let currentView = markRaw({
                    template: this.config.template,
                    components: { rxAjax,ShareFormBoListPreview },
                    mixins: [PublicFunction, shareFunction, FormCustomPublic],
                    ...script_
                })
                this.currentView = currentView;
                this.loadStyle();
            }
        },
        /**
         * 初始化自定义查询.
         */
        initQuery(){
            //自定义查询
            let params = {};
            let self = this;
            if(!this.config.customSql){
                return;
            }

            let alias = JSON.parse(this.config.customSql).value;
            let parameter = {};
            if (this.config.receive.type == 'url') {
                //取路由参数
                let routeParams = this.getRouterParams();
                let mapping = this.config.receive.mapping;
                if (mapping && mapping.length > 0) {
                    for (let i = 0; i < mapping.length; i++) {
                        let value = "";
                        if (mapping[i].valueSource == 'param') {
                            if (this.config.receive.type == "url") {
                                if (routeParams[mapping[i].valueDef]) {
                                    value = routeParams[mapping[i].valueDef];
                                }
                            } else {
                                if (routeParams[mapping[i].name]) {
                                    value = routeParams[mapping[i].name];
                                }
                            }
                        }
                        params[mapping[i].name] = value;
                    }
                }
            }
            this.params = params;
            this.getParams(this.config.receive.mapping, function (res) {
                if (res) {
                    Object.assign(params, res);
                }
                if (params) {
                    parameter.params = JSON.stringify(params);
                }
                self.getCustomQueryData(alias, parameter);
            })

        },
        //获取自定义查询数据
        getCustomQueryData(alias, parameter) {
            FormCustomQueryApi.doQuery(alias, parameter).then(res => {
                if (res.success && res.data) {
                    this.customQueryData = res.data;
                }
            });
        },
        //加载css
        loadStyle() {
            let cssStyle = "<style scoped>" + this.config.cssStyle + "</style>"
            let style = "";
            let styleMath = cssStyle.match(/<style scoped>([\s\S]*)<\/style>/) || cssStyle.match(/<style>([\s\S]*)<\/style>/);
            if (styleMath != null) {
                style = styleMath[1];
            }
            let newStyle = document.getElementById("customStyle" + this.config.alias);
            if (!newStyle) {
                newStyle = document.createElement('style');
                document.getElementsByTagName('head')[0].appendChild(newStyle)
            }
            newStyle.id = "customStyle" + this.config.alias;
            newStyle.innerHTML = style;
        },
        //发布事件
        customViewEvent(data) {
            //触发事件
            this.$bus.emit("formCustomViewEvent", data);
        },
        //处理事件传参
        handPublicReceive(args) {
            //增加调用自定义方法.
            let method = args.method;
            let component = this.$refs[this.refAlias];
            //调用组件方法
            if (method) {
                let data = args.data;
                let func = component[method];

                if (!func) {
                    console.warn("请在当前组件中配置方法:" + method);
                    return;
                }
                if (data) {
                    func(data);
                } else {
                    func();
                }
                return;
            }

            let receive = this.config.receive;
            let inputParams = args.params;
            let params = {};
            //自定义查询
            if (this.config.customSql) {
                let alias = JSON.parse(this.config.customSql).value;
                //通过自定义的事件
                if (args && args.type == "custom" && args.params) {
                    this.params = args.params;
                    this.getCustomQueryData(alias, { params: JSON.stringify(this.params) });
                    return;
                }
                //读取配置的参数
                for (let i = 0; i < receive.mapping.length; i++) {
                    let o = receive.mapping[i];
                    //处理没有配置值来源的情况。
                    if (!o.valueDef && inputParams[o.name]) {
                        params[o.name] = inputParams[o.name]
                    }
                    else if (o.valueSource == 'param' && inputParams[o.valueDef]) {
                        params[o.name] = inputParams[o.valueDef];
                    }
                }
                this.params = params;
                this.getCustomQueryData(alias, { params: JSON.stringify(params) });
                return;
            }
            else {
                //处理外部传的参数
                if (component["handCustomParams"]) {
                    component["handCustomParams"](args);
                }
            }
        },
    },
    watch: {},
}
</script>

<style scoped>
.custom-view {
    padding: 10px;
    background: white;
    height: 100%;
    overflow: auto;
}
</style>
